﻿using Amazon.SimpleEmail;
using Amazon.SimpleEmail.Model;
using FAMailUtils.MailGun;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FAGateway
{
    enum sendStatus : int
    {
        Sent = -1, Delivery = 0, Bounce = 1, Complain = 2, NotSend = 3
    }
    class SendItem
    {
        public decimal id { get; set; }
        public string From { get; set; }
        public string To { get; set; }
        public string CustomerName { get; set; }
        public string SenderName { get; set; }
        public string Subject { get; set; }
        public string Body { get; set; }
        public string messageId { get; set; }
        public sendStatus status { get; set; }
        public bool isSend { get; set; }
        public string exception { get; set; }
        public int sendRegisterId { get; set; }
        public int contentSendEventId { get; set; }
    }
    class EmailVerified
    {
        public bool isSetBounceTopic { get; set; }
        public bool isSetComplainTopic { get; set; }
        public string BounceTopic { get; set; }
        public string ComplainTopic { get; set; }
        public string Email { get; set; }

    }
    class AmazonCommon
    {
        log4net.ILog logs_error = log4net.LogManager.GetLogger("ErrorRollingLogFileAppender");
        log4net.ILog logs_info = log4net.LogManager.GetLogger("InfoRollingLogFileAppender");
        log4net.ILog logs_scan = log4net.LogManager.GetLogger("ScanEmailAppender");

        public string AccessKey { get; set; }
        public string SecretKey { get; set; }
        private AmazonSimpleEmailServiceClient client;
        public AmazonCommon(string accessKey, string secretKey)
        {
            AccessKey = accessKey;
            SecretKey = secretKey;
            client = new Amazon.SimpleEmail.AmazonSimpleEmailServiceClient(accessKey, secretKey);
        }
        public void GetQuotaInfo(out double TotalSend, out double maxSpeed, out double Max24HourSend)
        {
            GetSendQuotaRequest request = new GetSendQuotaRequest();
            GetSendQuotaResponse respone = client.GetSendQuota(request);
            maxSpeed = respone.GetSendQuotaResult.MaxSendRate;
            TotalSend = respone.GetSendQuotaResult.SentLast24Hours;
            Max24HourSend = respone.GetSendQuotaResult.Max24HourSend;
        }
        public SendItem SendMail(SendItem item)
        {
            try
            {
                SendEmailRequest request = new SendEmailRequest();
                List<string> toaddress = new List<string>();
                toaddress.Add(item.To);
                Destination des = new Destination(toaddress);
                request.Destination = des;
                request.Source = item.From;
                Amazon.SimpleEmail.Model.Message mes = new Amazon.SimpleEmail.Model.Message();
                mes.Body = new Body();
                mes.Body.Html = new Content(item.Body);
                mes.Subject = new Content(item.Subject);

                request.Message = mes;
                SendEmailResponse response = client.SendEmail(request);
                item.messageId = response.SendEmailResult.MessageId;
                item.isSend = true;
                item.exception = string.Format("Send Ok from {0} to {1}", item.From, item.To);
            }
            catch (Exception ex)
            {
                logs_error.Error("SendMail", ex); item.isSend = false;
                item.exception = string.Format("Send Ok from {0} to {1}\nException: {2}", item.From, item.To, ex.Message);
            }
            return item;
        }
        
        public List<EmailVerified> ListEmailVerifiedWithNotification()
        {
            List<EmailVerified> result = new List<EmailVerified>();
            try
            {
                client = new AmazonSimpleEmailServiceClient(AccessKey, SecretKey);
                List<String> verifiedEmailAddresses = ListVerifiedEmailAddresses();
                GetIdentityNotificationAttributesRequest request = new GetIdentityNotificationAttributesRequest();
                request.Identities = verifiedEmailAddresses;
                GetIdentityNotificationAttributesResponse response = client.GetIdentityNotificationAttributes(request);
                if (response != null)
                {
                    foreach (var item in response.GetIdentityNotificationAttributesResult.NotificationAttributes)
                    {
                        EmailVerified email = new EmailVerified();
                        email.Email = item.Key;
                        email.isSetBounceTopic = item.Value.BounceTopic != null;
                        email.isSetComplainTopic = item.Value.ComplaintTopic != null;
                        email.BounceTopic = item.Value.BounceTopic;
                        email.ComplainTopic = item.Value.ComplaintTopic;
                        result.Add(email);
                    }
                }
            }
            catch (Exception ex) { logs_error.Error("ListEmailVerifiedWithNotification", ex); }
            return result;
        }
        public List<string> ListVerifiedEmailAddresses()
        {
            List<string> verifiedEmailList = new List<string>();
            try
            {
                Amazon.SimpleEmail.Model.ListVerifiedEmailAddressesRequest request = new Amazon.SimpleEmail.Model.ListVerifiedEmailAddressesRequest();
                Amazon.SimpleEmail.Model.ListVerifiedEmailAddressesResponse response = new Amazon.SimpleEmail.Model.ListVerifiedEmailAddressesResponse();

                response = client.ListVerifiedEmailAddresses(request);
                if (client != null)
                {
                    if (response.ListVerifiedEmailAddressesResult != null)
                    {
                        if (response.ListVerifiedEmailAddressesResult.VerifiedEmailAddresses != null)
                        {
                            verifiedEmailList.AddRange(response.ListVerifiedEmailAddressesResult.VerifiedEmailAddresses);
                        }
                    }
                }
            }
            catch (Exception ex) { logs_error.Error("ListVerifiedEmailAddresses", ex); }
            return verifiedEmailList;
        }

        internal bool SetBounceTopic(string Email, string BounceTopic)
        {
            try
            {
                SetIdentityNotificationTopicRequest request = new SetIdentityNotificationTopicRequest();
                request.NotificationType = "Bounce";
                request.Identity = Email;
                request.SnsTopic = BounceTopic;
                SetIdentityNotificationTopicResponse response = client.SetIdentityNotificationTopic(request);
                return true;
            }
            catch (Exception ex)
            { logs_error.Error("SetBounceTopic", ex); return false; }
        }
        internal bool SetComplainTopic(string Email, string ComplainTopic)
        {

            try
            {
                SetIdentityNotificationTopicRequest request = new SetIdentityNotificationTopicRequest();
                request.NotificationType = "Complaint";
                request.Identity = Email;
                request.SnsTopic = ComplainTopic;
                SetIdentityNotificationTopicResponse response = client.SetIdentityNotificationTopic(request);

                return true;
            }
            catch (Exception ex)
            { logs_error.Error("SetComplainTopic", ex); return false; }
        }

        internal void UpdateSendItem(AmazonSesBouncedRecipient item)
        {
            try
            {
                string sql = "Update tblSendMail set sendStatus=@sendStatus where messageId=@messageId";
                using (SqlConnection connect = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"]))
                {

                    SqlCommand cmd = new SqlCommand(sql, connect);
                    connect.Open();
                    SqlParameter para = new SqlParameter("messageId", SqlDbType.NVarChar, 150);
                    para.Value = item.MessageId;
                    cmd.Parameters.Add(para);

                    para = new SqlParameter("@sendStatus", SqlDbType.Int);
                    para.Value = sendStatus.Bounce;
                    cmd.Parameters.Add(para);
                    cmd.ExecuteNonQuery();

                    cmd = new SqlCommand("SP_LogBounceEmail", connect);
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add(new SqlParameter("@FromEmail", SqlDbType.NVarChar, 250)).Value = item.FromEmail;
                    cmd.Parameters.Add(new SqlParameter("@ToEmail", SqlDbType.NVarChar, 250)).Value = item.EmailAddress;
                    cmd.Parameters.Add(new SqlParameter("@SendTime", SqlDbType.NVarChar, 250)).Value = item.SendTime;
                    cmd.Parameters.Add(new SqlParameter("@BounceType", SqlDbType.NVarChar, 250)).Value = item.BounceType;
                    cmd.ExecuteNonQuery();
                }
            }
            catch (Exception ex)
            { logs_error.Error("UpdateSendItem", ex); }
        }

        internal bool RegisterEmail(string email)
        {
            bool result = false;
            try
            {
                client = new AmazonSimpleEmailServiceClient(AccessKey, SecretKey);
                List<String> verifiedEmailAddresses = ListVerifiedEmailAddresses();
                VerifyEmailAddressRequest request = new VerifyEmailAddressRequest();
                VerifyEmailAddressResponse response = new VerifyEmailAddressResponse();
                if (!verifiedEmailAddresses.Contains(email))
                {
                    if (client != null)
                    {
                        request.EmailAddress = email.Trim();
                        response = client.VerifyEmailAddress(request);
                        if (!string.IsNullOrEmpty(response.ResponseMetadata.RequestId))
                        {
                            result = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            { logs_error.Error("RegisterEmail", ex); }
            return result;
        }
    }
}
